package com.gz;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class _Test {
    public static void main(String[] args) throws Exception {
        //获取A类对应的Class对象
        Class<?> aClass = Class.forName("com.gz.A");//方法一
//        Class<A> aClass1 = A.class;//方法二(共六种方法得到Class对象)
        System.out.println(aClass);
        Field[] declaredFields = aClass.getDeclaredFields();//获得所有成员变量
        for (Field declaredField : declaredFields) {//declared表示获取所有的，包括private和protected
            System.out.println(declaredField);
        }
        Constructor<?> constructor = aClass.getConstructor();
//        Object o = constructor.newInstance();
        Object o = aClass.newInstance();//调用无参
        Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(int.class,int.class);
        declaredConstructor.setAccessible(true);//爆破,使用反射可以访问private构造器
        Object o1 = declaredConstructor.newInstance(5,6);
        Method method = aClass.getMethod("show");
        method.invoke(o);//调用无参，不修改b的值
        System.out.println("======================");
        method.invoke(o1);//走o1构造器可以得到修改后的值，否则用o，调用无参构造，得到的是默认值0
        System.out.println("======================");
        method.invoke(o);
        System.out.println("======================");
        Field b = aClass.getDeclaredField("b");
//        System.out.println(b.get(o));  b是private，不进行b.setAccessible(true);爆破，不能访问(会报错)
        b.setAccessible(true);
        System.out.println(b.get(o));//0
        b.set(o,10);//用set来操作成员变量，私有变量爆破后才能操作
        System.out.println(b.get(o));//10
        method.invoke(o);//show()

        //调用有参方法,如果方法是私有的，必须要先爆破才能使用 (Method).setAccessible(true);
        Method method2 = aClass.getMethod("show2", String.class);
        method2.invoke(o,"你好");//有参()

    }

}

class A {
    static int a;
    private int b;
    public int c;
    public int d;

    public A() {
    }

    private A(int b, int d) {
        this.b = b;
        this.d = d;
    }
    public void show(){
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
    }

    public void show2(String s){
        System.out.println(s);
    }

}